package com.company.设计模式.代理模式;


import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 静态代理
 */
public class ProxyTest {
    private static  CglibProxy cglibProxy = new CglibProxy();
    private static UserService userService = new UserService();

    public static void main(String[] args) {
        System.out.println("--------------静态代理----------------");
        System.out.println("我要buy");
        //静态代理
        StaticProxy proxy = new StaticProxy();
        proxy.buy();
        System.out.println("--------------jdk动态代理----------------");
        JdkDynamicProxy jdkDynamicProxy = new JdkDynamicProxy();

        Subject instance = jdkDynamicProxy.getInstance(new RealSubject());
        System.out.println("jdk动态代理对象 "+instance.getClass().getSimpleName());
        instance.buy();
        System.out.println("--------------cglib动态代理----------------");

        UserService proxyInstance = (UserService) cglibProxy.getProxyInstance(userService);
        proxyInstance.print();
        System.out.println("-------------------------------");
        proxyInstance.printClassName();
    }
}


//抽象主题
interface  Subject{
    String buy();
}


//真实主题
class RealSubject implements Subject{

    @Override
    public String buy() {
        System.out.println("访问真实主题...");
        return "RealSubject";
    }
}


//静态代理
class StaticProxy implements Subject{


    //代理持有 对象
    private RealSubject realSubject = new RealSubject();

    @Override
    public String buy() {
        System.out.println("代理: 前置增强!");
        String res  = realSubject.buy();
        System.out.println("代理: 后置增强!");
        return res;
    }
}


//jdk动态代理
class JdkDynamicProxy implements InvocationHandler{

    //持有 代理目标对象
    private Object proxyTarget;

    //获取实例
    public <T> T getInstance(Object proxyTarget){
        this.proxyTarget = proxyTarget;
        return (T) Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(),
                proxyTarget.getClass().getInterfaces(),
                this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("jdk动态代理: 前置增强!");
        Object invoke = method.invoke(proxyTarget, args);
        System.out.println("proxyTarget 返回值" + invoke.toString());
        System.out.println("jdk动态代理: 后置增强!");
        return invoke;
    }
}

/**
 * -----------------cglib动态代理-------------------------
 */
//被代理对象类
@Component
class UserService {
    public void print() {
        System.out.println("==== 真正的业务逻辑 ====");
    }

    public void printClassName(){
        System.out.println(this.getClass().getSimpleName());
    }
}
//代理类
@Component
class CglibProxy implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        System.out.println("++++ 目标对象执行前逻辑 ++++");
        Object result = methodProxy.invokeSuper(obj, args);
        System.out.println("++++ 目标对象执行后逻辑 ++++");

        return result;
    }

    public Object getProxyInstance(Object target) {
        // 创建工具类
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(target.getClass());
        // 设置要织入的类
        enhancer.setCallback(this);

        // 返回代理对象
        return enhancer.create();
    }
}







